package com.iwhalecloud.bss.kite.cucc.service.spec.query;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.api.spec.query.IQueryAdditionalHotService;
import com.iwhalecloud.bss.kite.client.api.spec.query.IQueryOfferSpecService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.ProdInstDTO;
import com.iwhalecloud.bss.kite.client.dto.spec.MktResProductDTO;
import com.iwhalecloud.bss.kite.client.dto.spec.OfferDTO;
import com.iwhalecloud.bss.kite.common.cache.AbstractCache;
import com.iwhalecloud.bss.kite.common.constant.CoreDataConsts;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts2;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCompPrefRstrCfgCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.AttrValue;
import com.iwhalecloud.bss.kite.dataservice.entity.OfferCompPrefRstrCfg;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.MktResProdInfo;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferDetail;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Product;
import com.iwhalecloud.bss.kite.dataservice.mapper.spec.MktResourceMapper;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.graph.impl.RelEdge;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.zsmart.core.log.ZSmartLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Description: <br>
 * 公共服务类：简单服务方法不想新增一个服务时可共用此服务<br>
 *
 * @author xiepy<br>
 * @date 20190808<br>
 */
@Service
public class QueryAdditionalHotService implements IQueryAdditionalHotService {

    private String splitFlag = ",";

    protected static final ZSmartLogger LOGGER = ZSmartLogger.getLogger(QueryAdditionalHotService.class);

    @Autowired
    private IQueryOfferSpecService queryOfferSpecService;

    @Autowired
    IQuerySceneInstService querySceneInstService;

    @Autowired
    IQuerySceneInstService sceneInstQueryService;

    @Autowired
    private MktResourceMapper mktResourceMapper;

    /**
     * 查询主产品能订购热销终端资源
     *
     * @author xiepy<br>
     * @param prodId
     * @param lanId
     * @param provId
     * @param staffId
     * @return <br>
     */
    @Override
    public DataResult<List<MktResProductDTO>> getMktResProdByResCode(String prodId, String lanId, String provId,
        String staffId) {
        KiteObjectUtils.checkParamIsEmpty(prodId, "prodId");
        KiteObjectUtils.checkParamIsEmpty(lanId, "lanId");
        KiteObjectUtils.checkParamIsEmpty(provId, "provId");

        // 默认只查本地网配置售卖的终端
        MktResourceMapper mktResourceMapper = SpringUtil.getBean(MktResourceMapper.class);
        List<MktResProdInfo> mktResProdInfos = mktResourceMapper.selectMktResProdByProdId(prodId, null, lanId, null);

        if (KiteListUtils.isEmpty(mktResProdInfos)) {
            ErrorConsts.SUCCESS.getResult(null);
        }

        return ErrorConsts.SUCCESS.getResult(KiteBeanUtils.copyPropsForList(mktResProdInfos, MktResProductDTO.class));
    }

    @Override
    public DataResult<List<MktResProductDTO>> listGiftMktRes(String offerId, String prodId, String roleId, String lanId,
        String provId) {
        List<MktResProdInfo> mktResProdInfos = mktResourceMapper.listGiftMktRes(offerId, prodId, roleId);
        return ErrorConsts.SUCCESS.getResult(KiteBeanUtils.copyPropsForList(mktResProdInfos, MktResProductDTO.class));
    }

    /**
     * Description: <br>
     * 查询套餐下对应的热销可选包集合
     *
     * @author xiepy<br>
     * @taskId <br>
     * @param offerId 销售品ID (不能为空)
     * @param prodId 产品id
     * @param roleId 角色id（不能为空）
     * @param custId 客户ID
     * @param sceneInstId 场景标识
     * @return <br>
     */
    @Override
    public DataResult<List<OfferDTO>> listTopAdditionalOffers(String offerId, String prodId, String roleId,
        String custId, String sceneInstId) {
        List<OfferDTO> offers = new ArrayList<>();
        StringBuffer topOfferIds = new StringBuffer();
        // 销售品
        Offer offer = OfferCache.get(offerId);
        if (null == offer) {
            ErrorConsts.OFFER_NOT_EXISTS.throwOut(offerId);
        }

        // 基础销售品
        Product product = ProductCache.get(prodId);
        if (null == product) {
            ErrorConsts.PRODUCT_NOT_EXISTS.throwOut(prodId);
        }

        // 获取配置的热销可选包信息
        List<Offer> topOfferList = new ArrayList<Offer>();
        AbstractCache abstractCache = SpringUtil.getBean(KiteStringUtils.uncapitalize("AttrValueCache"));
        List<AttrValue> topAttrList = abstractCache.defaultGetObject("994001449");
        if (KiteListUtils.isEmpty(topAttrList)) {
            return ErrorConsts.SUCCESS.getResult(null);
        }
        LOGGER.debug("getMktResProdByResCode topAttrList.size = [{}]", topAttrList.size());

        topAttrList.forEach(AttrV -> {
            String offerIdV = AttrV.getAttrValue();
            if (KiteStringUtils.isNotEmpty(offerIdV) && KiteStringUtils.isNotEmpty(offerIdV.trim())) {
                Offer offerV = OfferCache.get(offerIdV.trim());
                if (offerV != null && KiteStringUtils.isNotEmpty(offerV.getOfferId())) {
                    topOfferList.add(offerV);
                    topOfferIds.append(splitFlag);
                    topOfferIds.append(offerV.getOfferId());
                    offerV = null;
                }
            }
        });
        if (KiteListUtils.isEmpty(topOfferList)) {
            return ErrorConsts.SUCCESS.getResult(null);
        }
        topOfferIds.append(splitFlag);
        LOGGER.debug("getMktResProdByResCode topOfferIds = [{}]", topOfferIds);
        List<OfferDTO> offerDTOList = null;
        for (Offer topOffer : topOfferList) {
            String offerName = topOffer.getOfferName();
            LOGGER.debug("getMktResProdByResCode offerName = [{}]", offerName);
            offerDTOList = queryOfferSpecService
                .listAllAdditionalOffersByOfferName(offerId, prodId, roleId, offerName, custId, sceneInstId)
                .getResultObject();
            if (KiteListUtils.isEmpty(offerDTOList)) {
                continue;
            }
            LOGGER.debug("getMktResProdByResCode offerDTOList.size = [{}]", offerDTOList.size());
            offerDTOList.forEach(offerV -> {
                if (KiteStringUtils.isIndexOf(topOfferIds.toString(), offerV.getOfferId(), splitFlag)) {
                    offers.add(offerV);
                }
            });
            offerDTOList.clear();
        }

        LOGGER.debug("getMktResProdByResCode offers.size = [{}]", offers.size());
        return ErrorConsts.SUCCESS.getResult(KiteListUtils.distinctByPropertyName(offers, "offerId"));
    }

    @Override
    public DataResult<List<OfferDTO>> listWithGiftAdditional(String custId, String giftOfferInstId,
        ProdInstDTO prodInst) {
        List<OfferDTO> giftAdditionalOffer = new ArrayList<>();
        KiteOfferInst giftOfferInst = querySceneInstService.getOfferInst(custId, giftOfferInstId);
        // 查询促销
        List<KiteOfferInst> offerPromotionInsts = querySceneInstService.listPromotionOfferInstsByProdInstId(custId,
            prodInst.getProdInstId());
        if (!KiteObjectUtils.isEmpty(offerPromotionInsts)) {
            for (KiteOfferInst kiteOfferInst : offerPromotionInsts) {
                RelEdge promotionOfferObjInstRel = sceneInstQueryService.getInstRel(custId,
                    InstType.PROMOTION_OFFER_INST, kiteOfferInst.getOfferInstId(), InstType.PROD_INST,
                    prodInst.getProdInstId(), RelType.OFFER_OBJ_REL_TYPE_1000);
                this.findCfgAdditionalOffer(promotionOfferObjInstRel, kiteOfferInst, prodInst, giftOfferInst,
                    giftAdditionalOffer);
            }
        }

        // 查询主套餐
        KiteOfferInst offerMainOfferInst = querySceneInstService.getMainOfferInstByProdInstId(custId,
            prodInst.getProdInstId());
        if (!KiteObjectUtils.isEmpty(offerMainOfferInst)) {
            RelEdge mainOfferObjInstRel = sceneInstQueryService.getInstRel(custId, InstType.MAIN_OFFER_INST,
                offerMainOfferInst.getOfferInstId(), InstType.PROD_INST, prodInst.getProdInstId(),
                RelType.OFFER_OBJ_REL_TYPE_1000);
            this.findCfgAdditionalOffer(mainOfferObjInstRel, offerMainOfferInst, prodInst, giftOfferInst,
                giftAdditionalOffer);
        }

        // 查询可选包
        List<KiteOfferInst> offerAdditionalInst = querySceneInstService.listOfferInstsByProdInstId(custId,
            prodInst.getProdInstId(), Lists.newArrayList(InstType.ADDITIONAL_OFFER_INST));
        if (!KiteObjectUtils.isEmpty(offerAdditionalInst)) {
            for (KiteOfferInst kiteOfferInst : offerAdditionalInst) {
                RelEdge additionalOfferObjInstRel = sceneInstQueryService.getInstRel(custId,
                    InstType.ADDITIONAL_OFFER_INST, kiteOfferInst.getOfferInstId(), InstType.PROD_INST,
                    prodInst.getProdInstId(), RelType.OFFER_OBJ_REL_TYPE_1000);
                this.findCfgAdditionalOffer(additionalOfferObjInstRel, kiteOfferInst, prodInst, giftOfferInst,
                    giftAdditionalOffer);
            }
        }

        // 去除重复的可选包
        return ErrorConsts.SUCCESS.getResult(KiteListUtils.distinctByPropertyName(giftAdditionalOffer, "offerId"));
    }

    public void findCfgAdditionalOffer(RelEdge offerObjInstRel, KiteOfferInst offerInst, ProdInstDTO prodInst,
        KiteOfferInst giftOfferInst, List<OfferDTO> giftAdditionalOffer) {
        String roleId;
        if (!KiteStringUtils.isEmpty(offerObjInstRel.getRoleId())) {
            roleId = offerObjInstRel.getRoleId();
        }
        else {
            roleId = prodInst.getRoleId();
        }
        String offerProdRelId = OfferCache.get(offerInst.getSpecId()).listOfferDetails().stream()
            .filter(offerDetail -> {
                return offerDetail.getObjId().equals(prodInst.getProdId())
                    && KiteStringUtils.equals(offerDetail.getRoleId(), roleId);
            }).map(OfferDetail::getOfferObjRelId).findFirst().orElse(null);
        List<OfferCompPrefRstrCfg> compPrefRstrCfgs = OfferCompPrefRstrCfgCache.get(giftOfferInst.getSpecId());
        for (OfferCompPrefRstrCfg offerCompCfg : compPrefRstrCfgs) {
            if (KiteStringUtils.equals(offerCompCfg.getOfferId(), offerInst.getSpecId())
                && KiteStringUtils.equals(offerCompCfg.getRoleId(), roleId)
                && KiteStringUtils.equals(offerCompCfg.getRstrType(), CoreDataConsts.OFFER_COMP_PREF_RSTR_TYPE_1100)
                // 增加对rel_type字段的过滤 -- gwx 2019-11-21
                && KiteStringUtils.equalsAny(offerCompCfg.getRelType(), KeyConsts2.OFFER_COMP_PREF_RSTR_CFG_1000,
                    KeyConsts2.OFFER_COMP_PREF_RSTR_CFG_1100)
                && !StringUtils.isEmpty(offerProdRelId)
                && KiteStringUtils.equals(offerCompCfg.getOfferProdRelId(), offerProdRelId)) {
                // 获取可选包规格
                Offer addirionalOffer = OfferCache.get(offerCompCfg.getPrefId());
                if (Objects.isNull(addirionalOffer)) {
                    // 如果查不到，直接跳过--可能是规格缓存没刷新到位，也可能是配置了约束但是实际没有这个销售品 -- gwx 2019-11-21
                    continue;
                }
                OfferDTO addirionalOfferDto = KiteBeanUtils.transform(addirionalOffer, OfferDTO.class);
                addirionalOfferDto.setType(KeyConsts.ADDITIONAL_PRODUCT_TYPE);
                giftAdditionalOffer.add(addirionalOfferDto);
            }
        }
    }

}
